
#include "cuda_runtime.h"
#include "device_launch_parameters.h"

#include <stdio.h>
#include "cpu_bitmap.h"
cudaError_t addWithCuda(int *c, const int *a, const int *b, unsigned int size);

#define DIM 250

//__global__ void addKernel(int *c, const int *a, const int *b)
//{
//
//}

/**
 * Fractals - Julia Set
 *
 *
 */



int main()
{
   //cpu version
	

}

struct CuComplex
{
	float r;
	float i;

	CuComplex(float a, float b) : r(a), i(b) {}
	float magnitude2(void)
	{
		return r * r + i * i;
	}

	CuComplex operator * (const CuComplex& a)
	{
		return CuComplex(r * a.r - i * a.i, i * a.r + r * a.i);
	}

	CuComplex operator + (const CuComplex& a)
	{
		return CuComplex(r + a.r, i + a.i);
	}


};


//finish this 
int GetJulia(int xValue, int yValue)
{
	const float scale = 1.5;
	float jX = scale + (float)(DIM / 2 - xValue) / (DIM / 2);

}

int CpuKernel(unsigned char * p_ptr)
{
	for (int yIndex = 0; yIndex < DIM; yIndex++)
	{
		for (int xIndex = 0; xIndex < DIM; xIndex++)
		{
			int offset = xIndex + yIndex * DIM;

			int juliaValue = GetJulia(xIndex, yIndex);

			p_ptr[offset * 4 + 0] = 255 * juliaValue;
			p_ptr[offset * 4 + 1] = 0;
			p_ptr[offset * 4 + 2] = 0;
			p_ptr[offset * 4 + 3] = 255;
		}
	}
}

int CpuJuliaSetExecution()
{
	CPUBitmap currentBitmap(DIM, DIM);
	unsigned char *ptr = currentBitmap.get_ptr();

	CpuKernel(ptr);

	currentBitmap.display_and_exit();
}

//// Helper function for using CUDA to add vectors in parallel.
//cudaError_t addWithCuda(int *c, const int *a, const int *b, unsigned int size)
//{
//    int *dev_a = 0;
//    int *dev_b = 0;
//    int *dev_c = 0;
//    cudaError_t cudaStatus;
//
//    // Choose which GPU to run on, change this on a multi-GPU system.
//    cudaStatus = cudaSetDevice(0);
//    if (cudaStatus != cudaSuccess) {
//        fprintf(stderr, "cudaSetDevice failed!  Do you have a CUDA-capable GPU installed?");
//        goto Error;
//    }
//
//    // Allocate GPU buffers for three vectors (two input, one output)    .
//    cudaStatus = cudaMalloc((void**)&dev_c, size * sizeof(int));
//    if (cudaStatus != cudaSuccess) {
//        fprintf(stderr, "cudaMalloc failed!");
//        goto Error;
//    }
//
//    cudaStatus = cudaMalloc((void**)&dev_a, size * sizeof(int));
//    if (cudaStatus != cudaSuccess) {
//        fprintf(stderr, "cudaMalloc failed!");
//        goto Error;
//    }
//
//    cudaStatus = cudaMalloc((void**)&dev_b, size * sizeof(int));
//    if (cudaStatus != cudaSuccess) {
//        fprintf(stderr, "cudaMalloc failed!");
//        goto Error;
//    }
//
//    // Copy input vectors from host memory to GPU buffers.
//    cudaStatus = cudaMemcpy(dev_a, a, size * sizeof(int), cudaMemcpyHostToDevice);
//    if (cudaStatus != cudaSuccess) {
//        fprintf(stderr, "cudaMemcpy failed!");
//        goto Error;
//    }
//
//    cudaStatus = cudaMemcpy(dev_b, b, size * sizeof(int), cudaMemcpyHostToDevice);
//    if (cudaStatus != cudaSuccess) {
//        fprintf(stderr, "cudaMemcpy failed!");
//        goto Error;
//    }
//
//    // Launch a kernel on the GPU with one thread for each element.
//    addKernel<<<1, size>>>(dev_c, dev_a, dev_b);
//
//    // Check for any errors launching the kernel
//    cudaStatus = cudaGetLastError();
//    if (cudaStatus != cudaSuccess) {
//        fprintf(stderr, "addKernel launch failed: %s\n", cudaGetErrorString(cudaStatus));
//        goto Error;
//    }
//    
//    // cudaDeviceSynchronize waits for the kernel to finish, and returns
//    // any errors encountered during the launch.
//    cudaStatus = cudaDeviceSynchronize();
//    if (cudaStatus != cudaSuccess) {
//        fprintf(stderr, "cudaDeviceSynchronize returned error code %d after launching addKernel!\n", cudaStatus);
//        goto Error;
//    }
//
//    // Copy output vector from GPU buffer to host memory.
//    cudaStatus = cudaMemcpy(c, dev_c, size * sizeof(int), cudaMemcpyDeviceToHost);
//    if (cudaStatus != cudaSuccess) {
//        fprintf(stderr, "cudaMemcpy failed!");
//        goto Error;
//    }
//
//Error:
//    cudaFree(dev_c);
//    cudaFree(dev_a);
//    cudaFree(dev_b);
//    
//    return cudaStatus;
//}
